<template>
  <div style="width: 100%;height: 100%">
    <div class="map" id="map"></div>
    <el-card id="popup" class="popup">
      <div class="popupContainer" id="popupContainer"></div>
    </el-card>
  </div>
</template>

<script>
import 'ol/ol.css';
import Map from 'ol/Map';
import Feature from 'ol/Feature';
import VectorSource from 'ol/source/Vector';
import Overlay from 'ol/Overlay';
import {Tile as TileLayer, Vector as VectorLayer} from 'ol/layer';
import View from 'ol/View';

import XYZ from 'ol/source/XYZ'
import Point from 'ol/geom/Point';
import { Icon, Style} from 'ol/style'
import markerImg from './monitor.png'
import popImg from './demo.png'

import Vue from 'vue'

import ImgPlayer from '@/views/screen/ImgPlayer/index.vue'
export default {
  name: "openlayersMap",
  data () {
    return {
      mapObj: null,
      mapDom: null,
      mapPointList: [],
      pointLayerSource:null,
      pointLayer: null,
      markerIcon: markerImg
    }
  },
  mounted() {
    this.initMap()
  },
  methods: {
    // 清除地图 某些情况 地图容器会存在两个 导致地图无法正常显示 这个问题折腾了我半天。
    // 找了半天官方貌似也没有提供 对应的 api，自己动手了。
    mapClear (){
      if (this.mapDom) {
        this.mapDom.innerHTML = ''
        this.mapDom = null
      }
    },
    
    // 初始化地图
    initMap () {
      // 先尝试清除
      this.mapClear()
      // 获取地图容器
      this.mapDom = document.getElementById('map')

      // 初始化地图配置
      this.mapObj = new Map({
        target: this.mapDom, // 地图容器
        view: new View({
          center: [123.424257, 41.653109], // 地图中心点
          zoom: 16, // 缩放
          projection: 'EPSG:4326' // 坐标系
        })
      })

      // 添加一个使用离线瓦片地图的层
      const offlineMapLayer = new TileLayer({
        source: new XYZ({
          url: "http://localhost:8080/SystemData/maps/NEU/{z}/{x}/{y}.jpg",
          // url: 'http://192.168.1.109:8081' + '/{z}/{x}/{y}.jpg'  // 设置本地离线瓦片所在路径
        })
      })
      // 将图层添加到地图
      this.mapObj.addLayer(offlineMapLayer)

      // 加载地理坐标
      this.addPoint()
      this.mapOnClick ()
    },

     // 地图点击事件
    mapOnClick (){
      const self = this

      // popupDom
      const popupDom = document.getElementById('popup')
      // 创建 popup
      const popup = new Overlay({
        element: popupDom,
        positioning: 'bottom-center',
        stopEvent: false
      })
      // 加载到地图
      this.mapObj.addOverlay(popup)

      // 地图点击事件
      this.mapObj.on('click', function (evt) {
        // 获取点击位置的数据
        const feature = self.mapObj.forEachFeatureAtPixel(evt.pixel, function (feature) {
          return feature;
        })

        // 根据 点击元素 className 判断是否点击在自定义popup上
        const isClickPopUp = evt.originalEvent.path.map(item => item.className).includes('el-card__body')
        if (!isClickPopUp) {
          popupDom.style.display = 'none'
        }

        // 官方示例 采用 jq + bootstrap弹窗，但是我觉得没有必要 如果大量使用bootstrap 组件可以考虑引入。
        

        // 判断数据
        if (feature) {
          // feature.values_.data ，data字段是在 addPoint 函数创建point时添加 可以自定义
          if (feature.values_.data) {
            const pointData = feature.values_.data
            popup.setPosition(evt.coordinate)
            const popupContainer = document.getElementById('popupContainer')
            let imgComponent = Vue.extend(ImgPlayer)
            // popupContainer.innerHTML = `<div><img src="${pointData.name}"></div>`
            let imgInstance = new imgComponent().$mount()
            popupContainer.appendChild(imgInstance.$el)
                // 或者渲染为文档之外的的元素并随后挂载
    // let textAreaInstance = new textAreaComponent({ 'content': content }).$mount()
    // container.appendChild(textAreaInstance.$el)

            popupDom.style.display = 'block'
          }
        }
      })
    },
    // 添加地理坐标
    addPoint () {
      this.delPointAll()
      // 地理坐标数组
      const pointData = [
        {longitude: 123.424257, latitude: 41.653109, name: popImg,id:1},
      ]

      pointData.map(item => {
        // 创建点
        const point = new Feature({
          geometry: new Point([item.longitude, item.latitude]),
          data: item
        })

        // 点的样式
        // eslint-disable-next-line no-undef
        const iconStyle = new Style({
          // eslint-disable-next-line no-undef
          image: new Icon({
            color: '#ffffff',
            crossOrigin: 'anonymous',
            src: this.markerIcon,
          }),
        })
        // 设置样式
        point.setStyle(iconStyle)
        // 保存到数据  方便删除
        this.mapPointList.push(point)
      })

      // 创建geojson据源
      this.pointLayerSource = new VectorSource({features: this.mapPointList})
      // 创建图层 并加载数据
      this.pointLayer = new VectorLayer({source: this.pointLayerSource})
      // 将图层添加地图上
      this.mapObj.addLayer(this.pointLayer)
    },

    // 地理点位删除
    delPointAll(){
      // 判断 删除的数据源是否存在
      if (this.pointLayerSource) {
        // 遍历删除
        this.mapPointList.map(item => {
          this.pointLayerSource.removeFeature(item)
        })

        // 删除图层 重置数据
        this.mapObj.removeLayer(this.pointLayer)
        this.pointLayerSource = null
        this.pointLayer = null
        this.mapPointList = []
      }
    }
  },
  beforeDestroy() {
    this.mapClear()
  }
}
</script>

<style scoped>
.map {
  width: 100%;
  height: 600px;
  /* margin-left: 30%; */
}
.popupContainer {
    position:absolute;
  top:50%;
  left:50%;
  display:block;
  transform:translate(-50%,-50%);
  height: 100%;
  width: 100%;
  min-width: 100%;
  min-height: 100%;
}

.popup {
  position: relative;
    height: 190px;
    width: 340px;  
}
</style>
